#pragma once
#include <QString>
#include <QHash>
#include <QSharedPointer>
#include <QStack>
#include <QMutex>
#include <QMutexLocker>

#include "base.h"
#include "exception.h"

namespace apollo
{
	namespace core
	{
		typedef QSharedPointer<Base> (*Creator)(const Container *container);
		
		class Container
		{
		private:
			struct Component
			{
				QString key;
				QSharedPointer<Base> object;
				Creator creator;
				QMutex locker;
				bool lazy;
			};
		public:
			Container(void);
			~Container(void);
			QSharedPointer<Base> resolve(const QString &key);
			template<typename T>
			QSharedPointer<T> resolve(const QString &key);
			void registerCreator(const QString &key, Creator creator, bool lazy = true);
			void start();
		private:
			QHash<QString, Component* > components;
			QStack<QSharedPointer<Base> > disposer;
			
		};
	}}
